package com.thwj.project.system.service.impl;

import cn.hutool.core.lang.Dict;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.thwj.common.exception.CustomException;
import com.thwj.common.utils.DateUtils;
import com.thwj.common.utils.StringUtils;
import com.thwj.common.utils.file.FileUtils;
import com.thwj.framework.config.properties.OssProperties;
import com.thwj.framework.web.domain.ResultCode;
import com.thwj.project.system.domain.SysOss;
import com.thwj.project.system.mapper.SysOssMapper;
import com.thwj.project.system.service.ISysDictDataService;
import com.thwj.project.system.service.ISysOssService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * oss 文件上传Service业务层处理
 *
 * @author 可乐
 * @date 2022-03-20
 */
@Service
public class SysOssServiceImpl implements ISysOssService {
    @Autowired
    private SysOssMapper sysOssMapper;
    @Autowired
    private OSS ossClient;

    @Autowired
    private OssProperties ossConfig;

    @Autowired
    private ISysDictDataService iSysDictDataService;

    private static final Logger log = LoggerFactory.getLogger(SysOssServiceImpl.class);


    @Override
    public List<SysOss> selectSysOssList(SysOss sysOss) {
        return sysOssMapper.selectSysOssList(sysOss);
    }


    @Override
    public List<SysOss> insertSysOsss(MultipartFile[] file, int size) {
        List<SysOss> sysObss = new ArrayList<>();
        for (int i = 0; i < file.length; i++) {
            try {
                String fileName = this.checkFile(file[i].getOriginalFilename(), file[i].getSize(), size);
                log.info("fileName:  " + fileName);
                SysOss sysOss = this.uploadFileToObs(file[i], fileName);
                //            雪花算法
                IdentifierGenerator identifierGenerator = new DefaultIdentifierGenerator();
                sysOss.setId(identifierGenerator.nextId(new Object()).toString());
                sysObss.add(sysOss);
            } catch (CustomException e) {
                log.info(e.getMessage());
                throw new CustomException(e.getMessage(), e.getCode());
            }
        }
        int count = sysOssMapper.insertSysOssList(sysObss);
        if (count != sysObss.size()) {
            log.info("resultCode" + ResultCode.FILE_FAILURE);
            throw new CustomException(ResultCode.FILE_FAILURE);
        }
        return sysObss;
    }

    @Override
    public SysOss addSysOsss(MultipartFile file, int size) throws CustomException {
        log.info("文件开始添加------ 时间{}", DateUtils.getNowDateTime());
        SysOss sysOss = null;
        try {
            String fileName = this.checkFile(file.getOriginalFilename(), file.getSize(), size);
            sysOss = this.uploadFileToObs(file, fileName);
            int count = sysOssMapper.insertSysOss(sysOss);
            if (count == 0) {
                log.info("文件插入失败:  " + ResultCode.FILE_FAILURE);
                throw new CustomException(ResultCode.FILE_FAILURE);
            }
        } catch (CustomException e) {
            log.info("其他错误信息:  " + e.getMessage());
            log.info("其他错误信息码:  " + e.getCode());
            throw new CustomException(e.getMessage(), e.getCode());
        }
        log.info("文件结束添加------ 时间{}", DateUtils.getNowDateTime());
        return sysOss;

    }

    @Override
    public SysOss addWaybillsToSysOss(MultipartFile file, int size) throws CustomException {
        return null;
    }

    @Override
    public SysOss saveBufferedImageToPdf(BufferedImage image, String filePathName, String fileName, int size) {
        return null;
    }


    /**
     * 上传图片到obs
     *
     * @param file
     * @return
     * @throws CustomException
     */
    public SysOss uploadFileToObs(MultipartFile file, String fileName) throws CustomException {
        //--------------------
        SysOss sysOss = new SysOss();

        // 创建ObsClient实例
        log.info("osscline", ossClient.toString());
        Map<String, String> map = FileUtils.getFileNameType(file.getOriginalFilename());
        // 调用接口进行操作，例如上传对象
        try {
            ossClient.putObject(ossConfig.getBucketName(), fileName + "/" + map.get("name"), new ByteArrayInputStream(file.getBytes()));
            String fullFilePath = "https://" + ossConfig.getBucketName() + "." + ossConfig.getEndpoint() + "/" + fileName + "/" + map.get("name");
//            雪花算法
            IdentifierGenerator identifierGenerator = new DefaultIdentifierGenerator();
            sysOss.setId(identifierGenerator.nextId(new Object()).toString());
            sysOss.setNowName(map.get("name"));
            sysOss.setFileType(map.get("type"));
            sysOss.setUrl(fullFilePath);
            sysOss.setFileSize(file.getSize());
            sysOss.setOriginalName(file.getOriginalFilename());
            sysOss.setIsDelete(0);
            return sysOss;
        } catch (OSSException oe) {
            log.info("Error Message:" + oe.getErrorMessage());
            log.info("Error Code:" + oe.getErrorCode());
            log.info("Request ID:" + oe.getRequestId());
            log.info("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            log.info("Error Message:" + ce.getMessage());
        } finally {
            return sysOss;
        }

    }

    /**
     * 校验文件
     *
     * @param name
     * @param len
     * @param size
     * @return
     * @throws CustomException
     */
    public String checkFile(String name, Long len, int size) throws CustomException {
        log.info("原始文件名：" + name);
        //判断文件类型
        String type = FileUtils.getFileType(name);
        String fileName = this.isFile(type);
        log.info("fileName:  " + fileName);
        if (StringUtils.isEmpty(fileName)) {
            log.info("该文件格式不允许上传");

            throw new CustomException(ResultCode.FILE_TYEP_ERROR);
        }
        //判断文件大小
        if (size != 0) {
            boolean falg = FileUtils.isFileSize(len, size, "M");
            if (falg) {
                log.info("文件大小不允许为空");
                throw new CustomException(ResultCode.FILE_SIZE);
            }
        }
        return fileName;
    }

    /**
     * 校验文件是否可以上传
     *
     * @param type
     * @return
     */
    public String isFile(String type) {
        String fileName = "other";
        type = type.toLowerCase();
        //查询出枚举
        List<Dict> dicts = iSysDictDataService.dictTypeList("sys_file_oss");
        for (int i = 0; i < dicts.size(); i++) {
            if (dicts.get(i).getStr("label").equals(type)) {
                fileName = dicts.get(i).getStr("vaule");
            }
        }
        return fileName;
    }


    public String uploadFile2Oss(byte file[], String fileName) {
        ossClient.putObject(ossConfig.getBucketName(), "ercode/" + fileName, new ByteArrayInputStream(file));
        String fullFilePath = "https://" + ossConfig.getBucketName() + "." + ossConfig.getEndpoint() + "/ercode/" + fileName;
        return fullFilePath;
    }

}
